package kiyut.ekspos;

import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;

import kiyut.ekspos.prefs.GeneralPreferences;
import kiyut.ekspos.prefs.IIOPreferences;

import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.flexdock.docking.state.PersistenceException;
import org.flexdock.perspective.PerspectiveManager;
import org.flexdock.perspective.persist.PersistenceHandler;
import org.flexdock.perspective.persist.Persister;
import org.flexdock.perspective.persist.PerspectiveModel;
import org.flexdock.perspective.persist.xml.XMLPersister;
import org.flexdock.view.View;

import com.jgoodies.looks.LookUtils;
import com.jgoodies.looks.Options;
import com.jgoodies.looks.plastic.PlasticLookAndFeel;
import com.jgoodies.looks.plastic.theme.ExperienceBlue;

import fr.umlv.authentication.Connection;
import fr.umlv.authentication.SessionHandler;
import fr.umlv.cmis.gedconfig.GEDDockingPersistence;
import fr.umlv.main.SplashScreen;


// TODO: Auto-generated Javadoc
/**
 * The Class Ekspos.
 */
public class Ekspos {

	/**
	 * The main method.
	 *
	 * @param args the arguments
	 */
	public static void main(String[] args) {
		String path = null;

		if (args.length > 0 ) {
			path = args[0];
		}

		Ekspos ekspos = new Ekspos();
		ekspos.run(path);
	}

	/**
	 * Instantiates a new ekspos.
	 */
	public Ekspos() {
	}

	/**
	 * Run.
	 *
	 * @param path the path
	 */
	public void run(String path) {
		initialize();

		try {
			path = resolvePath(path);
		} catch (Exception ex) {
			System.err.println("Unable to resolve startup path.\n" + ex.getMessage());
			path = null;
		}
		final String absPath = path;

		Connection login = new Connection(this);
		//login=new Login(this);
		login.setSize(500,300);
		login.setLocationRelativeTo(login.getParent());
		//Put the GUI in front of window
		//login.setAlwaysOnTop(true);
		login.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		login.setVisible(true);

		try {
			while(SessionHandler.getClientSession()==null || SessionHandler.getLocale()==null){
				synchronized (this) {
					this.wait();
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				SplashScreen.getInstance().hideSplashScreen();
				showMainFrame(absPath);
			}
		});
	}

	/**
	 * Resolve path.
	 *
	 * @param path the path
	 * @return the string
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	private String resolvePath(String path) throws IOException {
		String newPath = null;

		if (path == null) {
			return newPath;
		}

		File file = new File(path);
		file = file.getCanonicalFile();

		newPath = file.getCanonicalPath();

		return newPath;
	}

	/**
	 * Initialize.
	 */
	private void initialize() {
		String osName = System.getProperty("os.name").toUpperCase();

		// set default swing bold to false, only for JVM 1.5 or above
		UIManager.put("swing.boldMetal", Boolean.FALSE);

		// set LaF
		LookAndFeel lnf = UIManager.getLookAndFeel();
		if (lnf != null && lnf.getID().equalsIgnoreCase("Metal")) {
			String lnfClassName = null;
			if (osName.startsWith("MAC")) {
				System.setProperty("com.apple.mrj.application.apple.menu.about.name", Application.getName());
				System.setProperty("apple.laf.useScreenMenuBar","true");
				lnfClassName = UIManager.getSystemLookAndFeelClassName();
			} else if (osName.startsWith("WINDOWS")) {
				UIManager.put("ClassLoader", LookUtils.class.getClassLoader());
				lnfClassName = UIManager.getSystemLookAndFeelClassName();
				Options.setUseNarrowButtons(false);
			} else {
				UIManager.put("ClassLoader", LookUtils.class.getClassLoader());
				lnfClassName = Options.getCrossPlatformLookAndFeelClassName();
				PlasticLookAndFeel.setTabStyle(PlasticLookAndFeel.TAB_STYLE_METAL_VALUE);
				PlasticLookAndFeel.setPlasticTheme(new ExperienceBlue());
				Options.setUseNarrowButtons(false);

				//PlasticLookAndFeel.setMyCurrentTheme(new ExperienceBlueDefaultFont());  // for CJK Font
			}

			if (lnfClassName != null) {
				try {
					UIManager.setLookAndFeel(lnfClassName);
				} catch (Exception ex) {
					System.err.println("Unable to set LookAndFeel, use default LookAndFeel.\n" + ex.getMessage());
				}
			}
		}

		// initialize preferences.
		GeneralPreferences.getInstance();
		IIOPreferences.getInstance();
	}

	/**
	 * Show main frame.
	 *
	 * @param path the path
	 */
	private void showMainFrame(String path) {

		BrowserWindow frame = BrowserWindow.getInstance();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		WindowManager.createInstance(frame);

		// setup the PerspectiveManager
		GEDDockingPersistence dp = new GEDDockingPersistence();
		PerspectiveManager.setPersistenceHandler(dp);
		frame.restoreDocking();
		
		
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent evt) {
				System.exit(0);
			}
		});

		frame.setViewer(new CmisViewer() {
			public void view(List<CmisObject> files, int index) {
				WindowManager.getInstance().openViewerWindow(files, index);
			}
		});

		View v2 = frame.mapViewPlugins.get(BrowserWindow.DOCKING_TREE_VIEW);
		if(v2!= null){

			if(v2.getParent() instanceof JTabbedPane){
				JTabbedPane tabbedPane = (JTabbedPane)v2.getParent();
				tabbedPane.setSelectedIndex(0);
				tabbedPane.setTabPlacement(JTabbedPane.TOP);
			}
		}
		
		View v3 = frame.mapViewPlugins.get(BrowserWindow.DOCKING_LIST_VIEW);
		if(v3!= null) {

			if(v3.getParent() instanceof JTabbedPane){
				JTabbedPane tabbedPane = (JTabbedPane)v3.getParent();
				tabbedPane.setSelectedIndex(0);
				tabbedPane.setTabPlacement(JTabbedPane.TOP);
			}
		}

		frame.setVisible(true);

	}

	/**
	 * The Class DockingPersistence.
	 */
	public static class DockingPersistence implements PersistenceHandler {
		
		/* (non-Javadoc)
		 * @see org.flexdock.perspective.persist.PersistenceHandler#store(java.lang.String, org.flexdock.perspective.persist.PerspectiveModel)
		 */
		public boolean store(String persistenceKey, PerspectiveModel perspectiveModel) throws IOException, PersistenceException {
			boolean saved = false;

			java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream(1024);
			try {
				boolean stored = createDefaultPersister().store(os, perspectiveModel);
				if (stored == true) {
					byte[] bytes = os.toByteArray();
					GeneralPreferences prefs = GeneralPreferences.getInstance();
					prefs.putByteArray(GeneralPreferences.DOCKING_LAYOUT_KEY,bytes);
					prefs.save();
					saved = true;
				}
			} finally {
				os.close();
			}
			return saved;
		}

		/* (non-Javadoc)
		 * @see org.flexdock.perspective.persist.PersistenceHandler#load(java.lang.String)
		 */
		public PerspectiveModel load(String persistenceKey) throws IOException, PersistenceException {
			PerspectiveModel perspectiveModel = null;

			GeneralPreferences prefs = GeneralPreferences.getInstance();
			byte[] bytes = prefs.getByteArray(GeneralPreferences.DOCKING_LAYOUT_KEY);
			if (bytes != null) {
				java.io.ByteArrayInputStream is = new java.io.ByteArrayInputStream(bytes);
				try {
					perspectiveModel = createDefaultPersister().load(is);
				} finally {
					if (is != null) {
						is.close();
					}
				}
			}

			return perspectiveModel;
		}

		/* (non-Javadoc)
		 * @see org.flexdock.perspective.persist.PersistenceHandler#createDefaultPersister()
		 */
		public Persister createDefaultPersister() {
			return XMLPersister.newDefaultInstance();
		}

	}
}